package com.gzedu.frame.logic.net.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.tree.DefaultAttribute;
import org.dom4j.tree.DefaultElement;

/**
 * 
*<font color="#0000FF"> 
*<p>XMLParser.java</p>
*<p>XML解析器，方法体中大量用了递归与迭代，此方法已经实现通用接口适配解析</p>
*</font>
* @Package com.gzedu.frame.logic.net.xml
* @company:		广州远程教育中心有限公司
* @author :		戴俊林
* @date 2012-8-30 上午9:54:35
* @version V1.0
 */
public class XMLParser {
	

	/**
	 * 
	*<p>解析XML</p>
	* @param @param xml		XML数据
	* @param @return    
	* @return Map<String,Object>    
	* @throws
	 */
	public Map<String, Object> parserXML(String xml) {
		Map<String, Object> elementMap = new HashMap<String, Object>();
		Document doc = null;
		try {
			doc = DocumentHelper.parseText(xml); 
			Element rootElt = doc.getRootElement();
			elementMap = analysisElement(rootElt);
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return elementMap;
	}

	/**
	 * 
	*<p>解析Element节点数据</p>
	*<p>方法中存在迭代递归{@link #analysisElement}</p>
	* @param @param element
	* @param @return    
	* @return Map<String,Object>    
	* @throws
	* @see {@link #analysisAttribute(Element)}	解析节点上的属性
	 */
	private Map<String, Object> analysisElement(Element element) {
		Map<String, Object> map = new HashMap<String, Object>();
		String elementName = element.getName();
		Map<String, String> attributeMap = analysisAttribute(element);
		if (attributeMap != null && attributeMap.size() > 0) {
			map.put(elementName+"_attributeMap", attributeMap);
		}
		List<Map<String, Object>> parametersMap = analysisParameters(element);
		if (parametersMap != null && parametersMap.size() > 0) {
			map.put(elementName+"_parametersMap", parametersMap);
		}
		return map;
	}

	/**
	 * 
	*<p>解析节点上的属性</p>
	*<p>例如<Table id="1"> 上的id</p>
	* @param @param element
	* @param @return    
	* @return Map<String,String>    
	* @throws
	 */
	private Map<String, String> analysisAttribute(Element element) {
		@SuppressWarnings("unchecked")
		Iterator<DefaultAttribute> attributeIterator = element.attributeIterator();
		Map<String, String> attributeMap = new HashMap<String, String>();
		while (attributeIterator.hasNext()) {
			DefaultAttribute defaultAttribute = attributeIterator.next();
			String attributeName = defaultAttribute.getName();
			String attributeValue = defaultAttribute.getValue();
			if (attributeName != null && attributeName.trim().length() > 0
					&& attributeValue != null && attributeValue.trim().length() > 0) {
				attributeMap.put(attributeName, attributeValue);
			}
		}
		return attributeMap;
	}

	/**
	 * 
	*<p>解析父节点下的数据</p>
	* @param @param element
	* @param @return    
	* @return List<Map<String,Object>>    
	* @throws
	* @see {@link #analysisElement(Element)}
	 */
	private List<Map<String, Object>> analysisParameters(Element element) {
		Map<String, Object> parametersMap = new HashMap<String, Object>();
		List<Map<String, Object>> parametersList = new ArrayList<Map<String, Object>>();
		@SuppressWarnings("unchecked")
		Iterator<DefaultElement> elementIterator = element.elementIterator();
		while (elementIterator.hasNext()) {
			DefaultElement defaultElement = elementIterator.next();
			Map<String, Object> map = analysisElement(defaultElement);
			String defaultElementName = defaultElement.getName();
			String defaultElementText = defaultElement.getText();
			if (defaultElementName != null && defaultElementName.trim().length() > 0
					&& defaultElementText != null && defaultElementText.trim().length() > 0) {
				parametersMap.put(defaultElementName, defaultElementText);
			}
			if (map != null && map.size() > 0 && defaultElementText.trim().length() == 0) {
				parametersList.add(map);
			}
		}
		if(parametersMap!=null&&parametersMap.size()>0){
			parametersList.add(parametersMap);
		}
		return parametersList;
	}
}
